package com.heliming.data.utils;

import com.alibaba.fastjson.JSONObject;
import com.heliming.data.entity.Account;

import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collections;

public class JWTLoginFilter extends AbstractAuthenticationProcessingFilter {

	private final Logger logger = LoggerFactory.getLogger(JWTLoginFilter.class);

	public JWTLoginFilter(AuthenticationManager authenticationManager) {
		super(new AntPathRequestMatcher("/login"));
		setAuthenticationManager(authenticationManager);
	}

	// 接收并解析用户凭证
	@Override
	public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res)
			throws AuthenticationException, IOException {
		String body = IOUtils.toString(req.getInputStream(), "UTF-8");

		if (!HttpMethod.POST.equals(req.getMethod())) {
			if (logger.isDebugEnabled()) {
				logger.debug(String.format("Authentication method not support,Request method : %s", req.getMethod()));
			}
		}
		Account account = JSONObject.parseObject(body, Account.class);
		return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(account.getUsername(),
				account.getPassword(), Collections.<GrantedAuthority>emptyList()));
	}

	// 用户成功登录后，这个方法会被调用，我们在这个方法里生成token
	@Override
	protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, FilterChain chain,
			Authentication auth) throws IOException, ServletException {
		String token = String.format("%s %s", JwtTokenUtils.TOKEN_PERFIX,
				JwtTokenUtils.generateToken(auth.getName(), auth.getAuthorities()));
		res.setHeader(JwtTokenUtils.HEADER_STRING, token);
		res.setHeader("Content-type", "text/json;charset=UTF-8");
		res.setCharacterEncoding("UTF-8");
		res.getWriter().write(ResultPage.successToJsonString(token));
	}

}
